/// @tags: Topo SAM ST
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

namespace BlueQuantum {

typedef long long LL;

int const N = 2e5 + 5, ST = 19;

struct Node {
  int l, r, x;
  inline bool operator>(Node const &rhs) const { return r - l > rhs.r - rhs.l; }
} a[N], b[N];

char s[N];
int n1, n2;
int tot = 1, lst = 1, ch[N * 2][26], len[N * 4], link[N * 4];
int pos[N], val[N * 8];
int st[ST][N * 2];
int dfn[N * 8], low[N * 8], bel[N * 8], cnt, c_cnt;
vector<int> scc[N * 8], va[N * 2], vb[N * 2];
LL dis[N * 8];
bool ins[N * 8];
int stk[N * 8], top;
int q[N * 8], hh, tt, deg[N * 8];

inline int insert(int c) {
  int cur = ++tot, pos = lst;
  lst = cur;
  len[cur] = len[pos] + 1;
  while (pos != 0 && ch[pos][c] == 0) ch[pos][c] = cur, pos = link[pos];
  if (pos == 0) return link[cur] = 1, cur;
  int q = ch[pos][c];
  if (len[q] == len[pos] + 1) return link[cur] = q, cur;
  int clone = ++tot;
  memcpy(ch[clone], ch[q], sizeof(ch[q]));
  link[clone] = link[q];
  link[q] = link[cur] = clone;
  len[clone] = len[pos] + 1;
  while (pos != 0 && ch[pos][c] == q) ch[pos][c] = clone, pos = link[pos];
  return cur;
}

template <size_t V_SIZ, size_t E_SIZ, bool directed>
struct Graph {
  struct Edge {
    int v, nxt;
  } e[directed ? E_SIZ : E_SIZ * 2];

  int e_cnt, heads[V_SIZ];

  inline int operator()(int index) { return heads[index]; }
  inline Edge &operator[](int index) { return e[index]; }

  inline void clear() {
    memset(heads, 0, sizeof(heads));
    e_cnt = 0;
  }

  inline void add(int u, int v) {
    e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
  }
};

Graph<N * 8, N * 8, true> G;
Graph<N * 2, N * 2, true> H;

inline void prework() {
  for (int i = 1; i <= tot; ++i) st[0][i] = link[i];
  for (int i = 1; i < ST; ++i) {
    for (int j = 1; j <= tot; ++j) st[i][j] = st[i - 1][st[i - 1][j]];
  }
}

inline int query(int l, int r) {
  int res = pos[l];
  for (int i = ST - 1; i >= 0; --i)
    if (len[st[i][res]] >= r - l + 1) res = st[i][res];
  return res;
}

void tarjan(int u) {
  dfn[u] = low[u] = ++cnt;
  stk[++top] = u;
  ins[u] = true;
  for (int i = G(u), v; i; i = G[i].nxt) {
    if (dfn[v = G[i].v] == 0) {
      tarjan(v);
      low[u] = min(low[u], low[v]);
    } else if (ins[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (low[u] == dfn[u]) {
    int tmp;
    ++c_cnt;
    do {
      tmp = stk[top--];
      bel[tmp] = c_cnt;
      ins[tmp] = false;
      scc[c_cnt].push_back(tmp);
    } while (tmp != u);
  }
}

inline void solve() {
  for (int i = 1; i <= c_cnt; ++i)
    if (scc[i].size() > 1) {
      LL sum = 0;
      for (vector<int>::iterator j = scc[i].begin(), jlim = scc[i].end(); j != jlim;
           ++j) {
        sum += val[*j];
      }
      if (sum > 0) {
        cout << "-1\n";
        return;
      }
    }
  for (int i = 1; i <= c_cnt; ++i) {
    for (vector<int>::iterator j = scc[i].begin(), jlim = scc[i].end(); j != jlim; ++j)
      for (int k = G(*j); k; k = G[k].nxt)
        if (bel[G[k].v] != i) ++deg[bel[G[k].v]];
  }
  hh = tt = 0;
  for (int i = 1; i <= c_cnt; ++i)
    if (!deg[i]) q[++tt] = i;
  while (hh < tt) {
    int i = q[++hh];
    for (vector<int>::iterator j = scc[i].begin(), jlim = scc[i].end(); j != jlim; ++j) {
      dis[i] += val[*j];
      for (int k = G(*j), v; k; k = G[k].nxt)
        if (bel[v = G[k].v] != i) {
          dis[bel[v]] = max(dis[bel[v]], dis[i]);
          --deg[bel[v]];
          if (deg[bel[v]] == 0) q[++tt] = bel[v];
        }
    }
  }
  LL ans = 0;
  for (int i = 1; i <= c_cnt; ++i) ans = max(ans, dis[i]);
  cout << ans << '\n';
}

inline bool cmp1(int x, int y) { return a[x].r - a[x].l > a[y].r - a[y].l; }
inline bool cmp2(int x, int y) { return b[x].r - b[x].l > b[y].r - b[y].l; }

void dfs(int u) {
  if (u != 1 && (va[u].empty() == false || vb[u].empty() == false)) {
    int newNode = u, lstLen = len[u], nxt, nxtq;
    vector<int>::iterator i = va[u].begin(), ilim = va[u].end();
    vector<int>::iterator j = vb[u].begin(), jlim = vb[u].end();
    while (i != ilim && j != jlim) {
      if (a[*i] > b[*j]) {
        nxt = a[*i].r - a[*i].l + 1;
        if (nxt == lstLen) a[*i].x = newNode;
        else {
          nxtq = ++tot;
          link[nxtq] = link[newNode];
          link[newNode] = a[*i].x = nxtq;
          newNode = nxtq;
        }
        G.add(a[*i].x + n1 + n2, *i);
        lstLen = nxt;
        ++i;
      } else {
        nxt = b[*j].r - b[*j].l + 1;
        if (nxt == lstLen) b[*j].x = newNode;
        else {
          nxtq = ++tot;
          link[nxtq] = link[newNode];
          link[newNode] = nxtq;
          b[*j].x = nxtq;
          newNode = nxtq;
        }
        lstLen = nxt;
        ++j;
      }
    }
    while (i != ilim) {
      nxt = a[*i].r - a[*i].l + 1;
      if (nxt == lstLen) a[*i].x = newNode;
      else {
        nxtq = ++tot;
        link[nxtq] = link[newNode];
        link[newNode] = nxtq;
        a[*i].x = nxtq;
        newNode = nxtq;
      }
      G.add(a[*i].x + n1 + n2, *i);
      lstLen = nxt;
      ++i;
    }
    while (j != jlim) {
      nxt = b[*j].r - b[*j].l + 1;
      if (nxt == lstLen) b[*j].x = newNode;
      else {
        nxtq = ++tot;
        link[nxtq] = link[newNode];
        link[newNode] = nxtq;
        b[*j].x = nxtq;
        newNode = nxtq;
      }
      lstLen = nxt;
      ++j;
    }
  }
  for (int i = H(u); i; i = H[i].nxt) dfs(H[i].v);
}

inline void init(int n) {
  memset(ch, 0, sizeof(ch));
  memset(val, 0, sizeof(val));
  memset(dfn, 0, sizeof(dfn));
  memset(low, 0, sizeof(low));
  memset(dis, 0, sizeof(dis));
  for (int i = 1; i <= c_cnt; ++i) scc[i].clear();
  for (int i = 1; i <= n * 2; ++i) va[i].clear(), vb[i].clear();
  G.clear(), H.clear();
  tot = lst = 1;
  cnt = c_cnt = hh = tt = top = 0;
}

inline int main() {
  int t, m;
  cin >> t;
  while (t--) {
    cin >> (s + 1);
    int n = strlen(s + 1);
    for (int i = n; i; --i) pos[i] = insert(s[i] - 'a');
    prework();
    int minA = n, maxB = 0;
    cin >> n1;
    for (int i = 1; i <= n1; ++i) {
      cin >> a[i].l >> a[i].r;
      minA = min(minA, a[i].r - a[i].l + 1);
      a[i].x = query(a[i].l, a[i].r);
      val[i] = a[i].r - a[i].l + 1;
    }
    cin >> n2;
    for (int i = 1; i <= n2; ++i) {
      cin >> b[i].l >> b[i].r;
      maxB = max(maxB, b[i].r - b[i].l + 1);
      b[i].x = query(b[i].l, b[i].r);
    }
    for (int i = 2; i <= tot; ++i) H.add(link[i], i);
    for (int i = 1; i <= n1; ++i) va[a[i].x].push_back(i);
    for (int i = 1; i <= n2; ++i) vb[b[i].x].push_back(i);
    for (int i = 1; i <= tot; ++i)
      sort(va[i].begin(), va[i].end(), cmp1), sort(vb[i].begin(), vb[i].end(), cmp2);
    dfs(1);
    for (int i = 2; i <= tot; ++i) G.add(link[i] + n1 + n2, i + n1 + n2);
    for (int i = 1; i <= n2; ++i) G.add(i + n1, b[i].x + n1 + n2);
    cin >> m;
    for (int i = 1, u, v; i <= m; ++i) cin >> u >> v, G.add(u, v + n1);
    for (int i = 1; i <= tot + n1 + n2; ++i)
      if (dfn[i] == 0) tarjan(i);
    solve();
    init(n);
  }
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("P5284 [十二省联考2019] 字符串问题.in", "r", stdin);
  freopen("P5284 [十二省联考2019] 字符串问题.out", "w", stdout);
#endif
#endif

  ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
